#include "Util.h"

namespace kt {

/******************************** Raw Line ************************************************/
ALC Util::alc(int arrValue1, int arrValue2) {
	//0:None 1:Left_Normal 2:Left_Warning, 0:None 1:Right_Normal 2:Right_Warning
	CString s = std::to_string(arrValue1) + "," + std::to_string(arrValue2);
	if (s == "0,1") return ALC::Right_Normal;
	else if (s == "0,2") return ALC::Right_Warning;
	else if (s == "1,0") return ALC::Left_Normal;
	else if (s == "2,0") return ALC::Left_Warning;
	return ALC::INVALID;
}

LineStyle Util::lineStyle(int type) {
	switch(type) {
		case 2: return LineStyle::RoadEdge;
		case 3: return LineStyle::Dashed;
		case 4: return LineStyle::Dashed_Solid;
		case 5: return LineStyle::Solid_Dashed;
		case 6: return LineStyle::Double_Dashed;
		case 7: return LineStyle::Double_Solid;
		case 11: return LineStyle::Deceleration_Solid;
		case 12: return LineStyle::Deceleration_Dashed;
	}
	return LineStyle::Solid;
}

CColor Util::lineColor(int colour) {
	switch(colour) {
		case 0: return Config::Line_DefGrey;
		case 2: return "yellow";
		case 3: return "blue";
		case 4: return "orange";
		case 5: return "red";
	}
	return Config::Line_DefColor;
}

LineEq Util::lineEq(const CVector<float>& C, float rawStart, float rawEnd) {
	LineEq eq;
	eq.C = C;
	eq.zStart = -rawStart;
	eq.zEnd = -rawEnd;

	if (Proj::isSQ() || Proj::isSSQK()) {
		eq.C[1] = eq.C[2] = eq.C[3] = 0;
		eq.zStart = 1000000;
		eq.zEnd = -eq.zStart;
	}

	return eq;
}

DCLC Util::dclc(int direction) {
	switch(direction) {
		case 1: return DCLC::ToLeft;
		case 2: return DCLC::ToRight;
	}
	return DCLC::INVALID;
}

/******************************** Raw Model ************************************************/
ModelType Util::modelType(int objClass) {
	switch (objClass) {
		case 0: case 4: return ModelType::Car;
		case 1: case 3: return ModelType::Bus;
		case 2: case 5: return ModelType::Truck;
		case 6: return ModelType::Bike;
		case 7: return ModelType::Moto;
		case 8: return ModelType::Person;
		case 9: return ModelType::Cone;
		case 10: return ModelType::Unknown;//@note effective ModelType::Unknown is ModelType::Undefined
	}
	return ModelType::Car;// default:CAR
}

P Util::modelPos(float hDist, float vDist) {// left-positive, front-positive; angle unit: radians
	return P(-hDist, -vDist);
}

Vec2 Util::relSpeed(float speedX, float speedY) {
	return Vec2(speedX, speedY);
}

MoveStatus Util::moveStatus(int dynamicProp) {
	switch(dynamicProp) {
		case 2: return MoveStatus::Moving;
		case 3: return MoveStatus::Still;
		case 4: return MoveStatus::Stopped;
		case 5: return MoveStatus::Slow;
	}
	return MoveStatus::INVALID;
}

CColor Util::modelColor(int objectColour) {
	CColor color;// color.isValid() == false
	switch(objectColour) {
		case 1: color = CColor("blue").lighter(125); break;
		case 2: color = CColor("yellow").lighter(125); break;
		case 3: color = CColor("red").lighter(125); break;
	}
	return color;
}

/**@note recv data just when the state changed */
ACC_TG Util::accTG(int accTimeLevel) {
	switch (accTimeLevel) {
		case 0: return ACC_TG::Off;
		case 1: return ACC_TG::Gear_First;
		case 2: return ACC_TG::Gear_Second;
		case 3: return ACC_TG::Gear_Third;
		case 4: return ACC_TG::Gear_Fourth;
	}
	return ACC_TG::INVALID;
}

/**@note recv data just when the state changed */
LDW Util::ldw(int switchStatus, int departureTowards) {
	if (switchStatus == 3) {// switch on
		if (departureTowards == 2)// left
			return LDW::From_Left_Warning;
		else if (departureTowards == 3)// right
			return LDW::From_Right_Warning;
	} else if (switchStatus == 0)
		return LDW::Off;
	return LDW::INVALID;
}

TailLamp Util::tailLamp(int brakeLights, int blinkInfo) {
	if (brakeLights == 1)
		return TailLamp::Brake_On;
	switch (blinkInfo) {
		case 2: return TailLamp::Turn_Left;
		case 3: return TailLamp::Turn_Right;
		case 4: return TailLamp::Turn_Both;
		default: return TailLamp::INVALID;
	}
	return TailLamp::Off;
}

}// end namespace